package laxproxy

import (
	"context"
	"github.com/gin-gonic/gin"
	"laxkits/lib/laxutils"
	"net/http"
)

/// 用于发消息时的组装包体
var msgcodec IHookCodec

// @Desc: 主页
// @param c
func MainPage(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", "")
}

// @Desc: 发送模拟发消息的请求
// @param c
func TrySendMsg(c *gin.Context) {
	/// 返回消息
	ch := make(chan *WebReplyNode)
	roleUid := laxutils.ToUInt64(c.PostForm("RoleUid"))
	protoId := laxutils.ToUInt32(c.PostForm("ProtoId"))
	body := c.PostForm("MsgBody")
	var serialBody []byte
	var err error
	var isRpc = false
	if v, ok := genProtoMgrInstance().Protocols[protoId]; ok {
		isRpc = v.Timeout > 0
		if serialBody, err = TryParseProtoFromString(v.ProtoArg, body); err != nil {
			http.NotFound(c.Writer, c.Request)
			return
		}
	} else {
		http.NotFound(c.Writer, c.Request)
		return
	}
	wholeMsg := msgcodec.TryBuildWholeMsg(protoId, isRpc, serialBody)
	if wholeMsg == nil {
		http.Error(c.Writer, "编码失败", http.StatusOK)
		return
	}
	reqNode := &WebSendMsgNode{
		ch:      ch,
		RoleUid: roleUid,
		ProtoId: protoId,
		SendMsg: wholeMsg,
	}
	genProtoMgrInstance().WebSendMsgChan <- reqNode
	select {
	case result := <-ch:
		if result.code != 0 {
			c.JSON(http.StatusOK, gin.H{
				"msg": string(result.msg),
			})
		} else {
			var retMsg string
			if v, ok := genProtoMgrInstance().Protocols[protoId]; ok {
				if retMsg, err = TryParseProtoFromByte(v.ProtoRes, result.msg); err != nil {
					c.JSON(http.StatusOK, gin.H{
						"msg": "返回了消息但是解析失败",
					})
					return
				}
			}
			c.JSON(http.StatusOK, gin.H{
				"msg": retMsg,
			})
		}
	}
	close(ch)
}

// @Desc: 生成协议参数
// @param c
func TryGenerateProtocol(c *gin.Context) {
	protoId := laxutils.ToUInt32(c.Query("protoId"))
	if node, ok := genProtoMgrInstance().Protocols[protoId]; ok {
		fillRet := TryGenerateProtoStr(node.ProtoArg)
		c.JSON(http.StatusOK, fillRet)
		return
	}
	c.JSON(http.StatusNotFound, "")
}

// / 在角角色列表
func GetOnlineUsers(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"users": GetOnlineRoleList(),
	})
}

// / 协议列表
func GetProtocolList(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"protos": genProtoMgrInstance().ProtocolList,
	})
}

func GenProtoServe(ctx context.Context, port int, codec IHookCodec) {
	msgcodec = codec
	go genProtoMgrInstance().Start(ctx)
	gin.DisableConsoleColor()
	gin.SetMode(gin.ReleaseMode)
	r := gin.Default().Delims("[[", "]]")
	r.LoadHTMLGlob("web/html/*")
	r.Static("/web", "./web")
	r.GET("/", MainPage)
	r.GET("/users", GetOnlineUsers)
	r.GET("/protos", GetProtocolList)
	r.GET("/genproto", TryGenerateProtocol)
	r.POST("/send", TrySendMsg)
	r.Run(":" + laxutils.ToString(port))
}
